﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Linq;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace RssReader
{
    public partial class FeedDetailsPage : PhoneApplicationPage
    {
        private const string FeedKey = "FeedKey";
        private const string FeedName = "FeedName";

        object _selectedFeedItem;
        object _selectedFeed;

        FeedViewModel currentFeed;

        bool alreadyHookedScrollEvents = false;
        bool _scrolling = false;

        public FeedDetailsPage()
        {
            #region attach handlers
            InitializeComponent();
            SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
            PageTransitionDetails.Completed += new EventHandler(PageTransitionDetails_Completed);
            Loaded += new RoutedEventHandler(PhoneApplicationPage_Loaded);
            PageTransitionList.Completed += new EventHandler(PageTransitionList_Completed);
            #endregion
            LoadFeed();
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        { 
            // The following code deals with tombstoning.
            // It stores the key state required by the page to resume correctly for the user
            
              //try to locate the phone number from previous save and simply override it   
                if (true == PhoneApplicationService.Current.State.ContainsKey(FeedKey))   
              {   
                  //clear prev value   
                  PhoneApplicationService.Current.State.Remove(FeedKey);  
              }

              PhoneApplicationService.Current.State.Add(FeedKey, currentFeed.FeedUrl);

              //try to locate the phone number from previous save and simply override it   
              if (true == PhoneApplicationService.Current.State.ContainsKey(FeedName))
              {
                  //clear prev value   
                  PhoneApplicationService.Current.State.Remove(FeedName);
              }

              PhoneApplicationService.Current.State.Add(FeedName, currentFeed.FeedName);

        }

        private void LoadFeed()
        {
            FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
            currentFeed = root.DataContext as FeedViewModel;

            if (currentFeed == null)
            {
                if (true == PhoneApplicationService.Current.State.ContainsKey(FeedKey))
                {
                    // If we have resumed from tombstone, the currentfeed will be null 
                    // and our state will be saved in the transient state ready for retrieval
                    currentFeed = new FeedViewModel();
                    currentFeed.FeedUrl = PhoneApplicationService.Current.State[FeedKey] as string;
                    currentFeed.FeedName = PhoneApplicationService.Current.State[FeedName] as string;
                }
            }
            
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
            wc.DownloadStringAsync(new Uri(currentFeed.FeedUrl));
            _selectedFeed = currentFeed;
        }

        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // this method has to be modified to meet with the content contained in the RSS feed
            // It is currently set up for a feed with just article abstracts
            // The commented out code can be reinstated to support full articles in the feed
            // The bindings need to be changed in the screens also.

            //XNamespace x = @"http://purl.org/rss/1.0/modules/content/";
            //item.Element(x + "encoded").Value

            var rssFeed = XElement.Parse(e.Result);
            var currentFeed = this.DataContext as FeedViewModel;
            string pd = "";
            var items = from item in rssFeed.Descendants("item")
                        select new FeedItemViewModel()
                        {
                            Title = item.Element("title").Value,
                            DatePublished = item.Element("pubDate").Value,
                            Url = item.Element("link").Value,
                            Description = item.Element("description").Value
                            //Content = item.Element("description").Value

                        };
            
            foreach (var item in items)
                currentFeed.Items.Add(item);

            loadingBar.Visibility = System.Windows.Visibility.Collapsed;

        }
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            ResetPageTransitionList.Begin();
            this.DataContext = _selectedFeed;

            if (alreadyHookedScrollEvents)
                return;

            alreadyHookedScrollEvents = true;
            ScrollViewer viewer = FindSimpleVisualChild<ScrollViewer>(lstFeeds);
            if (viewer != null)
            {
                // Visual States are always on the first child of the control template 
                FrameworkElement element = VisualTreeHelper.GetChild(viewer, 0) as FrameworkElement;
                if (element != null)
                {
                    VisualStateGroup group = FindVisualState(element, "ScrollStates");
                    if (group != null)
                    {
                        group.CurrentStateChanging += (s, args) => { if (args.NewState.Name == "Scrolling") _scrolling = true; else _scrolling = false; };
                    }
                }
            }

        }

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Cancel default navigation
            e.Cancel = true;
            // Do page ransition animation
            PageTransitionDetails.Begin();
        }

        void PageTransitionDetails_Completed(object sender, EventArgs e)
        {
            // Reset root frame to MainPage.xaml
            PhoneApplicationFrame root = (PhoneApplicationFrame)Application.Current.RootVisual;
            root.GoBack();
        }


        private void lstFeeds_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (_scrolling == false)
            {
                // Capture selected item data
                _selectedFeedItem = (sender as ListBox).SelectedItem;
                if (_selectedFeedItem != null)
                {
                    // Start page transition animation
                    PageTransitionList.Begin();
                }
            }
        }
        private void PageTransitionList_Completed(object sender, EventArgs e)
        {
            // Set datacontext of details page to selected listbox item
            NavigationService.Navigate(new Uri("/FeedItemDetailsPage.xaml", UriKind.Relative));
            FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
            root.DataContext = _selectedFeedItem;
        }

        private void lstFeeds_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        VisualStateGroup FindVisualState(FrameworkElement element, string name)
        {
            if (element == null)
                return null;

            System.Collections.IList groups = VisualStateManager.GetVisualStateGroups(element);
            foreach (VisualStateGroup group in groups)
                if (group.Name == name)
                    return group;

            return null;
        }

        T FindSimpleVisualChild<T>(DependencyObject element) where T : class
        {
            while (element != null)
            {

                if (element is T)
                    return element as T;

                element = VisualTreeHelper.GetChild(element, 0);
            }

            return null;
        } 
      
    }
}